package services;

import java.util.Collection;
import java.util.Date;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import repositories.ActaRepository;
import domain.Acta;
import domain.Administrador;
import domain.ComunidadDeVecinos;
import domain.Reunion;
import domain.Vecino;

@Service
@Transactional
public class ActaService {

	// Managed Repository
	@Autowired
	private ActaRepository actaRepository;

	@Autowired
	private CuotaService cuotaService;
	
	@Autowired
	private AdministradorService administradorService;

	// Supporting Services
	@Autowired
	private VecinoService vecinoService;

	@Autowired
	private ReunionService reunionService;

	@Autowired
	private ComunidadDeVecinosService comunidadDeVecinosService;

	// Constructors
	public ActaService() {
		super();
	}

	// Simple CRUD methods

	public Acta findOne(int actaId) {
		Acta result;

		result = actaRepository.findOne(actaId);

		return result;
	}

	// Other Business methods

	public Collection<Acta> findActasByComunidadDeVecinos(
			int comunidadDeVecinosId) {
		
		Collection<Acta> result;

		result = actaRepository
				.findActasByComunidadDeVecinos(comunidadDeVecinosId);
		

		return result;
	}

	public Collection<Acta> findActasMorosoByComunidadDeVecinos(
			int comunidadDeVecinosId) {
		Collection<Acta> result;

		result = actaRepository
				.findActasMorosoByComunidadDeVecinos(comunidadDeVecinosId);

		return result;
	}

	public Collection<Acta> findActasMorosoByVecinoMoroso(int vecinoMorosoId) {
		Collection<Acta> result;
		Vecino moroso;
		Administrador principal;
		
		principal = administradorService.findByPrincipal();
		Assert.isTrue(principal instanceof Administrador);
		moroso = vecinoService.findOne(vecinoMorosoId);
		Assert.isTrue(moroso.getMoroso());

		result = actaRepository.findActasMorosoByVecinoMoroso(vecinoMorosoId);

		return result;
	}

	public Acta create(int reunionId) {
		Acta res;
		Reunion reunion;
		ComunidadDeVecinos comunidad;
		Vecino principal;

		principal = vecinoService.findByPrincipal();

		reunion = reunionService.findOne(reunionId);
		Assert.isTrue(reunion.getComunidadDeVecinos().getPresidente()
				.equals(principal));

		Assert.isTrue(reunion.getActas() == null
				|| reunion.getActas().isEmpty());
		Assert.isTrue(reunion.getFechaCelebracion().before(new Date()));

		comunidad = comunidadDeVecinosService.findOne(reunion
				.getComunidadDeVecinos().getId());

		res = new Acta();
		res.setFecha(new Date(System.currentTimeMillis()-1000));
		res.setReunion(reunion);
		res.setComunidadDeVecinos(comunidad);

		return res;
	}

	public void save(Acta acta) {
		Assert.notNull(acta);

		Double importe;
		Vecino principal;
		Reunion reunion;
		Assert.isTrue(acta.getFecha().before(new Date()));
		principal = vecinoService.findByPrincipal();

		importe = acta.getReunion().getImporte();
		reunion = reunionService.findOne(acta.getReunion().getId());
		Assert.isTrue(reunion.getFechaCelebracion().before(acta.getFecha()));
		Assert.isTrue(reunion.getComunidadDeVecinos().getPresidente()
				.equals(principal));
		Assert.isTrue(acta.getTipo().equals("Moroso")
				|| acta.getTipo().equals("Ordinaria")
				|| acta.getTipo().equals("Extraordinaria")
				|| acta.getTipo().equals("Otras"));
		Assert.isTrue(acta.getComunidadDeVecinos().equals(
				acta.getReunion().getComunidadDeVecinos()));

		if (acta.getTipo().equals("Moroso")) {
			Assert.notNull(acta.getVecinoMoroso());
		}

		if (acta.getTipo().equals("Ordinaria")
				|| acta.getTipo().equals("Extraordinaria")) {
			Assert.isTrue(reunion.getImporte() != null
					|| reunion.getImporte() > 0.0);

			if (acta.getTipo().equals("Ordinaria")) {
				acta.getComunidadDeVecinos().setImporteCuota(importe);
			} else {
				cuotaService.generarCuotaExtraOrdinaria(acta
						.getComunidadDeVecinos().getId(), importe);

			}
		}
		Assert.notNull(acta.getDecisiones());
		actaRepository.save(acta);

	}

	public void delete(Acta a) {
		Assert.notNull(a);
		actaRepository.delete(a);
		
	}
}
